# coding:utf-8
import time


def check_token(conn, token):
    # 尝试获取并返回令牌对应的用户
    return conn.hget('login:', token)


def update_token(conn, token, user, item=None):
    # 获取当前时间戳
    timestamp = time.time()
    # 维持令牌与已登录用户之间的映射
    conn.hset('login:', token, user)
    # 记录令牌最后一次出现的时间
    conn.zadd('recent:', token, timestamp)
    if item:
        # 记录用户浏览过的商品
        conn.zadd('viewed:' + token, item, timestamp)
        # 移除旧的记录，只保留用户最近浏览过的25个商品
        conn.zremrangebyrank('viewed:' + token, 0, -26)
        # 这行代码是新添加的: from 2.5 网页分析
        conn.zincrby('viewed:', item, -1)


QUIT = False
LIMIT = 10000000


def clean_sessions(conn):
    while not QUIT:
        # 找出目前已有令牌的数量。
        size = conn.zcard('recent:')
        # 令牌数量未超过限制，休眠并在之后重新检查。
        if size <= LIMIT:
            time.sleep(1)
            continue

        # 获取需要移除的令牌ID
        end_index = min(size - LIMIT, 100)
        tokens = conn.zrange('recent:', 0, end_index - 1)

        # 为那些将要删除的令牌构建键名
        session_keys = []
        for token in tokens:
            session_keys.append('viewed:' + token)

        # 移除最旧的那些令牌。
        conn.delete(*session_keys)
        conn.hdel('login:', *tokens)
        conn.zrem('recent:', *tokens)


def rescale_viewed(conn):
    while not QUIT:
        # 删除所有排名在 20000 名之后的商品。
        conn.zremrangebyrank('viewed:', 0, -20001)
        # 将浏览次数降低为原来的一半。
        conn.zinterstore('viewed:', {'viewed:': .5})
        # 5 分钟之后再次执行这个操作。
        time.sleep(300)



